home *** CD-ROM | disk | FTP | other *** search
/ Freelog 100 / FreelogNo100-NovembreDecembre2010.iso / Musique / solfege / solfege-win32-3.17.0.exe / {app} / bin / Lib / httplib.py < prev    next >
Text File  |  2008-02-14  |  49KB  |  1,433 lines

  1. """HTTP/1.1 client library
  2.  
  3. <intro stuff goes here>
  4. <other stuff, too>
  5.  
  6. HTTPConnection goes through a number of "states", which define when a client
  7. may legally make another request or fetch the response for a particular
  8. request. This diagram details these state transitions:
  9.  
  10.     (null)
  11.       |
  12.       | HTTPConnection()
  13.       v
  14.     Idle
  15.       |
  16.       | putrequest()
  17.       v
  18.     Request-started
  19.       |
  20.       | ( putheader() )*  endheaders()
  21.       v
  22.     Request-sent
  23.       |
  24.       | response = getresponse()
  25.       v
  26.     Unread-response   [Response-headers-read]
  27.       |\____________________
  28.       |                     |
  29.       | response.read()     | putrequest()
  30.       v                     v
  31.     Idle                  Req-started-unread-response
  32.                      ______/|
  33.                    /        |
  34.    response.read() |        | ( putheader() )*  endheaders()
  35.                    v        v
  36.        Request-started    Req-sent-unread-response
  37.                             |
  38.                             | response.read()
  39.                             v
  40.                           Request-sent
  41.  
  42. This diagram presents the following rules:
  43.   -- a second request may not be started until {response-headers-read}
  44.   -- a response [object] cannot be retrieved until {request-sent}
  45.   -- there is no differentiation between an unread response body and a
  46.      partially read response body
  47.  
  48. Note: this enforcement is applied by the HTTPConnection class. The
  49.       HTTPResponse class does not enforce this state machine, which
  50.       implies sophisticated clients may accelerate the request/response
  51.       pipeline. Caution should be taken, though: accelerating the states
  52.       beyond the above pattern may imply knowledge of the server's
  53.       connection-close behavior for certain requests. For example, it
  54.       is impossible to tell whether the server will close the connection
  55.       UNTIL the response headers have been read; this means that further
  56.       requests cannot be placed into the pipeline until it is known that
  57.       the server will NOT be closing the connection.
  58.  
  59. Logical State                  __state            __response
  60. -------------                  -------            ----------
  61. Idle                           _CS_IDLE           None
  62. Request-started                _CS_REQ_STARTED    None
  63. Request-sent                   _CS_REQ_SENT       None
  64. Unread-response                _CS_IDLE           <response_class>
  65. Req-started-unread-response    _CS_REQ_STARTED    <response_class>
  66. Req-sent-unread-response       _CS_REQ_SENT       <response_class>
  67. """
  68.  
  69. import errno
  70. import mimetools
  71. import socket
  72. from urlparse import urlsplit
  73.  
  74. try:
  75.     from cStringIO import StringIO
  76. except ImportError:
  77.     from StringIO import StringIO
  78.  
  79. __all__ = ["HTTP", "HTTPResponse", "HTTPConnection", "HTTPSConnection",
  80.            "HTTPException", "NotConnected", "UnknownProtocol",
  81.            "UnknownTransferEncoding", "UnimplementedFileMode",
  82.            "IncompleteRead", "InvalidURL", "ImproperConnectionState",
  83.            "CannotSendRequest", "CannotSendHeader", "ResponseNotReady",
  84.            "BadStatusLine", "error", "responses"]
  85.  
  86. HTTP_PORT = 80
  87. HTTPS_PORT = 443
  88.  
  89. _UNKNOWN = 'UNKNOWN'
  90.  
  91. # connection states
  92. _CS_IDLE = 'Idle'
  93. _CS_REQ_STARTED = 'Request-started'
  94. _CS_REQ_SENT = 'Request-sent'
  95.  
  96. # status codes
  97. # informational
  98. CONTINUE = 100
  99. SWITCHING_PROTOCOLS = 101
  100. PROCESSING = 102
  101.  
  102. # successful
  103. OK = 200
  104. CREATED = 201
  105. ACCEPTED = 202
  106. NON_AUTHORITATIVE_INFORMATION = 203
  107. NO_CONTENT = 204
  108. RESET_CONTENT = 205
  109. PARTIAL_CONTENT = 206
  110. MULTI_STATUS = 207
  111. IM_USED = 226
  112.  
  113. # redirection
  114. MULTIPLE_CHOICES = 300
  115. MOVED_PERMANENTLY = 301
  116. FOUND = 302
  117. SEE_OTHER = 303
  118. NOT_MODIFIED = 304
  119. USE_PROXY = 305
  120. TEMPORARY_REDIRECT = 307
  121.  
  122. # client error
  123. BAD_REQUEST = 400
  124. UNAUTHORIZED = 401
  125. PAYMENT_REQUIRED = 402
  126. FORBIDDEN = 403
  127. NOT_FOUND = 404
  128. METHOD_NOT_ALLOWED = 405
  129. NOT_ACCEPTABLE = 406
  130. PROXY_AUTHENTICATION_REQUIRED = 407
  131. REQUEST_TIMEOUT = 408
  132. CONFLICT = 409
  133. GONE = 410
  134. LENGTH_REQUIRED = 411
  135. PRECONDITION_FAILED = 412
  136. REQUEST_ENTITY_TOO_LARGE = 413
  137. REQUEST_URI_TOO_LONG = 414
  138. UNSUPPORTED_MEDIA_TYPE = 415
  139. REQUESTED_RANGE_NOT_SATISFIABLE = 416
  140. EXPECTATION_FAILED = 417
  141. UNPROCESSABLE_ENTITY = 422
  142. LOCKED = 423
  143. FAILED_DEPENDENCY = 424
  144. UPGRADE_REQUIRED = 426
  145.  
  146. # server error
  147. INTERNAL_SERVER_ERROR = 500
  148. NOT_IMPLEMENTED = 501
  149. BAD_GATEWAY = 502
  150. SERVICE_UNAVAILABLE = 503
  151. GATEWAY_TIMEOUT = 504
  152. HTTP_VERSION_NOT_SUPPORTED = 505
  153. INSUFFICIENT_STORAGE = 507
  154. NOT_EXTENDED = 510
  155.  
  156. # Mapping status codes to official W3C names
  157. responses = {
  158.     100: 'Continue',
  159.     101: 'Switching Protocols',
  160.  
  161.     200: 'OK',
  162.     201: 'Created',
  163.     202: 'Accepted',
  164.     203: 'Non-Authoritative Information',
  165.     204: 'No Content',
  166.     205: 'Reset Content',
  167.     206: 'Partial Content',
  168.  
  169.     300: 'Multiple Choices',
  170.     301: 'Moved Permanently',
  171.     302: 'Found',
  172.     303: 'See Other',
  173.     304: 'Not Modified',
  174.     305: 'Use Proxy',
  175.     306: '(Unused)',
  176.     307: 'Temporary Redirect',
  177.  
  178.     400: 'Bad Request',
  179.     401: 'Unauthorized',
  180.     402: 'Payment Required',
  181.     403: 'Forbidden',
  182.     404: 'Not Found',
  183.     405: 'Method Not Allowed',
  184.     406: 'Not Acceptable',
  185.     407: 'Proxy Authentication Required',
  186.     408: 'Request Timeout',
  187.     409: 'Conflict',
  188.     410: 'Gone',
  189.     411: 'Length Required',
  190.     412: 'Precondition Failed',
  191.     413: 'Request Entity Too Large',
  192.     414: 'Request-URI Too Long',
  193.     415: 'Unsupported Media Type',
  194.     416: 'Requested Range Not Satisfiable',
  195.     417: 'Expectation Failed',
  196.  
  197.     500: 'Internal Server Error',
  198.     501: 'Not Implemented',
  199.     502: 'Bad Gateway',
  200.     503: 'Service Unavailable',
  201.     504: 'Gateway Timeout',
  202.     505: 'HTTP Version Not Supported',
  203. }
  204.  
  205. # maximal amount of data to read at one time in _safe_read
  206. MAXAMOUNT = 1048576
  207.  
  208. class HTTPMessage(mimetools.Message):
  209.  
  210.     def addheader(self, key, value):
  211.         """Add header for field key handling repeats."""
  212.         prev = self.dict.get(key)
  213.         if prev is None:
  214.             self.dict[key] = value
  215.         else:
  216.             combined = ", ".join((prev, value))
  217.             self.dict[key] = combined
  218.  
  219.     def addcontinue(self, key, more):
  220.         """Add more field data from a continuation line."""
  221.         prev = self.dict[key]
  222.         self.dict[key] = prev + "\n " + more
  223.  
  224.     def readheaders(self):
  225.         """Read header lines.
  226.  
  227.         Read header lines up to the entirely blank line that terminates them.
  228.         The (normally blank) line that ends the headers is skipped, but not
  229.         included in the returned list.  If a non-header line ends the headers,
  230.         (which is an error), an attempt is made to backspace over it; it is
  231.         never included in the returned list.
  232.  
  233.         The variable self.status is set to the empty string if all went well,
  234.         otherwise it is an error message.  The variable self.headers is a
  235.         completely uninterpreted list of lines contained in the header (so
  236.         printing them will reproduce the header exactly as it appears in the
  237.         file).
  238.  
  239.         If multiple header fields with the same name occur, they are combined
  240.         according to the rules in RFC 2616 sec 4.2:
  241.  
  242.         Appending each subsequent field-value to the first, each separated
  243.         by a comma. The order in which header fields with the same field-name
  244.         are received is significant to the interpretation of the combined
  245.         field value.
  246.         """
  247.         # XXX The implementation overrides the readheaders() method of
  248.         # rfc822.Message.  The base class design isn't amenable to
  249.         # customized behavior here so the method here is a copy of the
  250.         # base class code with a few small changes.
  251.  
  252.         self.dict = {}
  253.         self.unixfrom = ''
  254.         self.headers = hlist = []
  255.         self.status = ''
  256.         headerseen = ""
  257.         firstline = 1
  258.         startofline = unread = tell = None
  259.         if hasattr(self.fp, 'unread'):
  260.             unread = self.fp.unread
  261.         elif self.seekable:
  262.             tell = self.fp.tell
  263.         while True:
  264.             if tell:
  265.                 try:
  266.                     startofline = tell()
  267.                 except IOError:
  268.                     startofline = tell = None
  269.                     self.seekable = 0
  270.             line = self.fp.readline()
  271.             if not line:
  272.                 self.status = 'EOF in headers'
  273.                 break
  274.             # Skip unix From name time lines
  275.             if firstline and line.startswith('From '):
  276.                 self.unixfrom = self.unixfrom + line
  277.                 continue
  278.             firstline = 0
  279.             if headerseen and line[0] in ' \t':
  280.                 # XXX Not sure if continuation lines are handled properly
  281.                 # for http and/or for repeating headers
  282.                 # It's a continuation line.
  283.                 hlist.append(line)
  284.                 self.addcontinue(headerseen, line.strip())
  285.                 continue
  286.             elif self.iscomment(line):
  287.                 # It's a comment.  Ignore it.
  288.                 continue
  289.             elif self.islast(line):
  290.                 # Note! No pushback here!  The delimiter line gets eaten.
  291.                 break
  292.             headerseen = self.isheader(line)
  293.             if headerseen:
  294.                 # It's a legal header line, save it.
  295.                 hlist.append(line)
  296.                 self.addheader(headerseen, line[len(headerseen)+1:].strip())
  297.                 continue
  298.             else:
  299.                 # It's not a header line; throw it back and stop here.
  300.                 if not self.dict:
  301.                     self.status = 'No headers'
  302.                 else:
  303.                     self.status = 'Non-header line where header expected'
  304.                 # Try to undo the read.
  305.                 if unread:
  306.                     unread(line)
  307.                 elif tell:
  308.                     self.fp.seek(startofline)
  309.                 else:
  310.                     self.status = self.status + '; bad seek'
  311.                 break
  312.  
  313. class HTTPResponse:
  314.  
  315.     # strict: If true, raise BadStatusLine if the status line can't be
  316.     # parsed as a valid HTTP/1.0 or 1.1 status line.  By default it is
  317.     # false because it prevents clients from talking to HTTP/0.9
  318.     # servers.  Note that a response with a sufficiently corrupted
  319.     # status line will look like an HTTP/0.9 response.
  320.  
  321.     # See RFC 2616 sec 19.6 and RFC 1945 sec 6 for details.
  322.  
  323.     def __init__(self, sock, debuglevel=0, strict=0, method=None):
  324.         self.fp = sock.makefile('rb', 0)
  325.         self.debuglevel = debuglevel
  326.         self.strict = strict
  327.         self._method = method
  328.  
  329.         self.msg = None
  330.  
  331.         # from the Status-Line of the response
  332.         self.version = _UNKNOWN # HTTP-Version
  333.         self.status = _UNKNOWN  # Status-Code
  334.         self.reason = _UNKNOWN  # Reason-Phrase
  335.  
  336.         self.chunked = _UNKNOWN         # is "chunked" being used?
  337.         self.chunk_left = _UNKNOWN      # bytes left to read in current chunk
  338.         self.length = _UNKNOWN          # number of bytes left in response
  339.         self.will_close = _UNKNOWN      # conn will close at end of response
  340.  
  341.     def _read_status(self):
  342.         # Initialize with Simple-Response defaults
  343.         line = self.fp.readline()
  344.         if self.debuglevel > 0:
  345.             print "reply:", repr(line)
  346.         if not line:
  347.             # Presumably, the server closed the connection before
  348.             # sending a valid response.
  349.             raise BadStatusLine(line)
  350.         try:
  351.             [version, status, reason] = line.split(None, 2)
  352.         except ValueError:
  353.             try:
  354.                 [version, status] = line.split(None, 1)
  355.                 reason = ""
  356.             except ValueError:
  357.                 # empty version will cause next test to fail and status
  358.                 # will be treated as 0.9 response.
  359.                 version = ""
  360.         if not version.startswith('HTTP/'):
  361.             if self.strict:
  362.                 self.close()
  363.                 raise BadStatusLine(line)
  364.             else:
  365.                 # assume it's a Simple-Response from an 0.9 server
  366.                 self.fp = LineAndFileWrapper(line, self.fp)
  367.                 return "HTTP/0.9", 200, ""
  368.  
  369.         # The status code is a three-digit number
  370.         try:
  371.             status = int(status)
  372.             if status < 100 or status > 999:
  373.                 raise BadStatusLine(line)
  374.         except ValueError:
  375.             raise BadStatusLine(line)
  376.         return version, status, reason
  377.  
  378.     def begin(self):
  379.         if self.msg is not None:
  380.             # we've already started reading the response
  381.             return
  382.  
  383.         # read until we get a non-100 response
  384.         while True:
  385.             version, status, reason = self._read_status()
  386.             if status != CONTINUE:
  387.                 break
  388.             # skip the header from the 100 response
  389.             while True:
  390.                 skip = self.fp.readline().strip()
  391.                 if not skip:
  392.                     break
  393.                 if self.debuglevel > 0:
  394.                     print "header:", skip
  395.  
  396.         self.status = status
  397.         self.reason = reason.strip()
  398.         if version == 'HTTP/1.0':
  399.             self.version = 10
  400.         elif version.startswith('HTTP/1.'):
  401.             self.version = 11   # use HTTP/1.1 code for HTTP/1.x where x>=1
  402.         elif version == 'HTTP/0.9':
  403.             self.version = 9
  404.         else:
  405.             raise UnknownProtocol(version)
  406.  
  407.         if self.version == 9:
  408.             self.length = None
  409.             self.chunked = 0
  410.             self.will_close = 1
  411.             self.msg = HTTPMessage(StringIO())
  412.             return
  413.  
  414.         self.msg = HTTPMessage(self.fp, 0)
  415.         if self.debuglevel > 0:
  416.             for hdr in self.msg.headers:
  417.                 print "header:", hdr,
  418.  
  419.         # don't let the msg keep an fp
  420.         self.msg.fp = None
  421.  
  422.         # are we using the chunked-style of transfer encoding?
  423.         tr_enc = self.msg.getheader('transfer-encoding')
  424.         if tr_enc and tr_enc.lower() == "chunked":
  425.             self.chunked = 1
  426.             self.chunk_left = None
  427.         else:
  428.             self.chunked = 0
  429.  
  430.         # will the connection close at the end of the response?
  431.         self.will_close = self._check_close()
  432.  
  433.         # do we have a Content-Length?
  434.         # NOTE: RFC 2616, S4.4, #3 says we ignore this if tr_enc is "chunked"
  435.         length = self.msg.getheader('content-length')
  436.         if length and not self.chunked:
  437.             try:
  438.                 self.length = int(length)
  439.             except ValueError:
  440.                 self.length = None
  441.         else:
  442.             self.length = None
  443.  
  444.         # does the body have a fixed length? (of zero)
  445.         if (status == NO_CONTENT or status == NOT_MODIFIED or
  446.             100 <= status < 200 or      # 1xx codes
  447.             self._method == 'HEAD'):
  448.             self.length = 0
  449.  
  450.         # if the connection remains open, and we aren't using chunked, and
  451.         # a content-length was not provided, then assume that the connection
  452.         # WILL close.
  453.         if not self.will_close and \
  454.            not self.chunked and \
  455.            self.length is None:
  456.             self.will_close = 1
  457.  
  458.     def _check_close(self):
  459.         conn = self.msg.getheader('connection')
  460.         if self.version == 11:
  461.             # An HTTP/1.1 proxy is assumed to stay open unless
  462.             # explicitly closed.
  463.             conn = self.msg.getheader('connection')
  464.             if conn and "close" in conn.lower():
  465.                 return True
  466.             return False
  467.  
  468.         # Some HTTP/1.0 implementations have support for persistent
  469.         # connections, using rules different than HTTP/1.1.
  470.  
  471.         # For older HTTP, Keep-Alive indiciates persistent connection.
  472.         if self.msg.getheader('keep-alive'):
  473.             return False
  474.  
  475.         # At least Akamai returns a "Connection: Keep-Alive" header,
  476.         # which was supposed to be sent by the client.
  477.         if conn and "keep-alive" in conn.lower():
  478.             return False
  479.  
  480.         # Proxy-Connection is a netscape hack.
  481.         pconn = self.msg.getheader('proxy-connection')
  482.         if pconn and "keep-alive" in pconn.lower():
  483.             return False
  484.  
  485.         # otherwise, assume it will close
  486.         return True
  487.  
  488.     def close(self):
  489.         if self.fp:
  490.             self.fp.close()
  491.             self.fp = None
  492.  
  493.     def isclosed(self):
  494.         # NOTE: it is possible that we will not ever call self.close(). This
  495.         #       case occurs when will_close is TRUE, length is None, and we
  496.         #       read up to the last byte, but NOT past it.
  497.         #
  498.         # IMPLIES: if will_close is FALSE, then self.close() will ALWAYS be
  499.         #          called, meaning self.isclosed() is meaningful.
  500.         return self.fp is None
  501.  
  502.     # XXX It would be nice to have readline and __iter__ for this, too.
  503.  
  504.     def read(self, amt=None):
  505.         if self.fp is None:
  506.             return ''
  507.  
  508.         if self.chunked:
  509.             return self._read_chunked(amt)
  510.  
  511.         if amt is None:
  512.             # unbounded read
  513.             if self.length is None:
  514.                 s = self.fp.read()
  515.             else:
  516.                 s = self._safe_read(self.length)
  517.                 self.length = 0
  518.             self.close()        # we read everything
  519.             return s
  520.  
  521.         if self.length is not None:
  522.             if amt > self.length:
  523.                 # clip the read to the "end of response"
  524.                 amt = self.length
  525.  
  526.         # we do not use _safe_read() here because this may be a .will_close
  527.         # connection, and the user is reading more bytes than will be provided
  528.         # (for example, reading in 1k chunks)
  529.         s = self.fp.read(amt)
  530.         if self.length is not None:
  531.             self.length -= len(s)
  532.  
  533.         return s
  534.  
  535.     def _read_chunked(self, amt):
  536.         assert self.chunked != _UNKNOWN
  537.         chunk_left = self.chunk_left
  538.         value = ''
  539.  
  540.         # XXX This accumulates chunks by repeated string concatenation,
  541.         # which is not efficient as the number or size of chunks gets big.
  542.         while True:
  543.             if chunk_left is None:
  544.                 line = self.fp.readline()
  545.                 i = line.find(';')
  546.                 if i >= 0:
  547.                     line = line[:i] # strip chunk-extensions
  548.                 chunk_left = int(line, 16)
  549.                 if chunk_left == 0:
  550.                     break
  551.             if amt is None:
  552.                 value += self._safe_read(chunk_left)
  553.             elif amt < chunk_left:
  554.                 value += self._safe_read(amt)
  555.                 self.chunk_left = chunk_left - amt
  556.                 return value
  557.             elif amt == chunk_left:
  558.                 value += self._safe_read(amt)
  559.                 self._safe_read(2)  # toss the CRLF at the end of the chunk
  560.                 self.chunk_left = None
  561.                 return value
  562.             else:
  563.                 value += self._safe_read(chunk_left)
  564.                 amt -= chunk_left
  565.  
  566.             # we read the whole chunk, get another
  567.             self._safe_read(2)      # toss the CRLF at the end of the chunk
  568.             chunk_left = None
  569.  
  570.         # read and discard trailer up to the CRLF terminator
  571.         ### note: we shouldn't have any trailers!
  572.         while True:
  573.             line = self.fp.readline()
  574.             if not line:
  575.                 # a vanishingly small number of sites EOF without
  576.                 # sending the trailer
  577.                 break
  578.             if line == '\r\n':
  579.                 break
  580.  
  581.         # we read everything; close the "file"
  582.         self.close()
  583.  
  584.         return value
  585.  
  586.     def _safe_read(self, amt):
  587.         """Read the number of bytes requested, compensating for partial reads.
  588.  
  589.         Normally, we have a blocking socket, but a read() can be interrupted
  590.         by a signal (resulting in a partial read).
  591.  
  592.         Note that we cannot distinguish between EOF and an interrupt when zero
  593.         bytes have been read. IncompleteRead() will be raised in this
  594.         situation.
  595.  
  596.         This function should be used when <amt> bytes "should" be present for
  597.         reading. If the bytes are truly not available (due to EOF), then the
  598.         IncompleteRead exception can be used to detect the problem.
  599.         """
  600.         s = []
  601.         while amt > 0:
  602.             chunk = self.fp.read(min(amt, MAXAMOUNT))
  603.             if not chunk:
  604.                 raise IncompleteRead(s)
  605.             s.append(chunk)
  606.             amt -= len(chunk)
  607.         return ''.join(s)
  608.  
  609.     def getheader(self, name, default=None):
  610.         if self.msg is None:
  611.             raise ResponseNotReady()
  612.         return self.msg.getheader(name, default)
  613.  
  614.     def getheaders(self):
  615.         """Return list of (header, value) tuples."""
  616.         if self.msg is None:
  617.             raise ResponseNotReady()
  618.         return self.msg.items()
  619.  
  620.  
  621. class HTTPConnection:
  622.  
  623.     _http_vsn = 11
  624.     _http_vsn_str = 'HTTP/1.1'
  625.  
  626.     response_class = HTTPResponse
  627.     default_port = HTTP_PORT
  628.     auto_open = 1
  629.     debuglevel = 0
  630.     strict = 0
  631.  
  632.     def __init__(self, host, port=None, strict=None):
  633.         self.sock = None
  634.         self._buffer = []
  635.         self.__response = None
  636.         self.__state = _CS_IDLE
  637.         self._method = None
  638.  
  639.         self._set_hostport(host, port)
  640.         if strict is not None:
  641.             self.strict = strict
  642.  
  643.     def _set_hostport(self, host, port):
  644.         if port is None:
  645.             i = host.rfind(':')
  646.             j = host.rfind(']')         # ipv6 addresses have [...]
  647.             if i > j:
  648.                 try:
  649.                     port = int(host[i+1:])
  650.                 except ValueError:
  651.                     raise InvalidURL("nonnumeric port: '%s'" % host[i+1:])
  652.                 host = host[:i]
  653.             else:
  654.                 port = self.default_port
  655.             if host and host[0] == '[' and host[-1] == ']':
  656.                 host = host[1:-1]
  657.         self.host = host
  658.         self.port = port
  659.  
  660.     def set_debuglevel(self, level):
  661.         self.debuglevel = level
  662.  
  663.     def connect(self):
  664.         """Connect to the host and port specified in __init__."""
  665.         msg = "getaddrinfo returns an empty list"
  666.         for res in socket.getaddrinfo(self.host, self.port, 0,
  667.                                       socket.SOCK_STREAM):
  668.             af, socktype, proto, canonname, sa = res
  669.             try:
  670.                 self.sock = socket.socket(af, socktype, proto)
  671.                 if self.debuglevel > 0:
  672.                     print "connect: (%s, %s)" % (self.host, self.port)
  673.                 self.sock.connect(sa)
  674.             except socket.error, msg:
  675.                 if self.debuglevel > 0:
  676.                     print 'connect fail:', (self.host, self.port)
  677.                 if self.sock:
  678.                     self.sock.close()
  679.                 self.sock = None
  680.                 continue
  681.             break
  682.         if not self.sock:
  683.             raise socket.error, msg
  684.  
  685.     def close(self):
  686.         """Close the connection to the HTTP server."""
  687.         if self.sock:
  688.             self.sock.close()   # close it manually... there may be other refs
  689.             self.sock = None
  690.         if self.__response:
  691.             self.__response.close()
  692.             self.__response = None
  693.         self.__state = _CS_IDLE
  694.  
  695.     def send(self, str):
  696.         """Send `str' to the server."""
  697.         if self.sock is None:
  698.             if self.auto_open:
  699.                 self.connect()
  700.             else:
  701.                 raise NotConnected()
  702.  
  703.         # send the data to the server. if we get a broken pipe, then close
  704.         # the socket. we want to reconnect when somebody tries to send again.
  705.         #
  706.         # NOTE: we DO propagate the error, though, because we cannot simply
  707.         #       ignore the error... the caller will know if they can retry.
  708.         if self.debuglevel > 0:
  709.             print "send:", repr(str)
  710.         try:
  711.             self.sock.sendall(str)
  712.         except socket.error, v:
  713.             if v[0] == 32:      # Broken pipe
  714.                 self.close()
  715.             raise
  716.  
  717.     def _output(self, s):
  718.         """Add a line of output to the current request buffer.
  719.  
  720.         Assumes that the line does *not* end with \\r\\n.
  721.         """
  722.         self._buffer.append(s)
  723.  
  724.     def _send_output(self):
  725.         """Send the currently buffered request and clear the buffer.
  726.  
  727.         Appends an extra \\r\\n to the buffer.
  728.         """
  729.         self._buffer.extend(("", ""))
  730.         msg = "\r\n".join(self._buffer)
  731.         del self._buffer[:]
  732.         self.send(msg)
  733.  
  734.     def putrequest(self, method, url, skip_host=0, skip_accept_encoding=0):
  735.         """Send a request to the server.
  736.  
  737.         `method' specifies an HTTP request method, e.g. 'GET'.
  738.         `url' specifies the object being requested, e.g. '/index.html'.
  739.         `skip_host' if True does not add automatically a 'Host:' header
  740.         `skip_accept_encoding' if True does not add automatically an
  741.            'Accept-Encoding:' header
  742.         """
  743.  
  744.         # if a prior response has been completed, then forget about it.
  745.         if self.__response and self.__response.isclosed():
  746.             self.__response = None
  747.  
  748.  
  749.         # in certain cases, we cannot issue another request on this connection.
  750.         # this occurs when:
  751.         #   1) we are in the process of sending a request.   (_CS_REQ_STARTED)
  752.         #   2) a response to a previous request has signalled that it is going
  753.         #      to close the connection upon completion.
  754.         #   3) the headers for the previous response have not been read, thus
  755.         #      we cannot determine whether point (2) is true.   (_CS_REQ_SENT)
  756.         #
  757.         # if there is no prior response, then we can request at will.
  758.         #
  759.         # if point (2) is true, then we will have passed the socket to the
  760.         # response (effectively meaning, "there is no prior response"), and
  761.         # will open a new one when a new request is made.
  762.         #
  763.         # Note: if a prior response exists, then we *can* start a new request.
  764.         #       We are not allowed to begin fetching the response to this new
  765.         #       request, however, until that prior response is complete.
  766.         #
  767.         if self.__state == _CS_IDLE:
  768.             self.__state = _CS_REQ_STARTED
  769.         else:
  770.             raise CannotSendRequest()
  771.  
  772.         # Save the method we use, we need it later in the response phase
  773.         self._method = method
  774.         if not url:
  775.             url = '/'
  776.         str = '%s %s %s' % (method, url, self._http_vsn_str)
  777.  
  778.         self._output(str)
  779.  
  780.         if self._http_vsn == 11:
  781.             # Issue some standard headers for better HTTP/1.1 compliance
  782.  
  783.             if not skip_host:
  784.                 # this header is issued *only* for HTTP/1.1
  785.                 # connections. more specifically, this means it is
  786.                 # only issued when the client uses the new
  787.                 # HTTPConnection() class. backwards-compat clients
  788.                 # will be using HTTP/1.0 and those clients may be
  789.                 # issuing this header themselves. we should NOT issue
  790.                 # it twice; some web servers (such as Apache) barf
  791.                 # when they see two Host: headers
  792.  
  793.                 # If we need a non-standard port,include it in the
  794.                 # header.  If the request is going through a proxy,
  795.                 # but the host of the actual URL, not the host of the
  796.                 # proxy.
  797.  
  798.                 netloc = ''
  799.                 if url.startswith('http'):
  800.                     nil, netloc, nil, nil, nil = urlsplit(url)
  801.  
  802.                 if netloc:
  803.                     try:
  804.                         netloc_enc = netloc.encode("ascii")
  805.                     except UnicodeEncodeError:
  806.                         netloc_enc = netloc.encode("idna")
  807.                     self.putheader('Host', netloc_enc)
  808.                 else:
  809.                     try:
  810.                         host_enc = self.host.encode("ascii")
  811.                     except UnicodeEncodeError:
  812.                         host_enc = self.host.encode("idna")
  813.                     if self.port == HTTP_PORT:
  814.                         self.putheader('Host', host_enc)
  815.                     else:
  816.                         self.putheader('Host', "%s:%s" % (host_enc, self.port))
  817.  
  818.             # note: we are assuming that clients will not attempt to set these
  819.             #       headers since *this* library must deal with the
  820.             #       consequences. this also means that when the supporting
  821.             #       libraries are updated to recognize other forms, then this
  822.             #       code should be changed (removed or updated).
  823.  
  824.             # we only want a Content-Encoding of "identity" since we don't
  825.             # support encodings such as x-gzip or x-deflate.
  826.             if not skip_accept_encoding:
  827.                 self.putheader('Accept-Encoding', 'identity')
  828.  
  829.             # we can accept "chunked" Transfer-Encodings, but no others
  830.             # NOTE: no TE header implies *only* "chunked"
  831.             #self.putheader('TE', 'chunked')
  832.  
  833.             # if TE is supplied in the header, then it must appear in a
  834.             # Connection header.
  835.             #self.putheader('Connection', 'TE')
  836.  
  837.         else:
  838.             # For HTTP/1.0, the server will assume "not chunked"
  839.             pass
  840.  
  841.     def putheader(self, header, value):
  842.         """Send a request header line to the server.
  843.  
  844.         For example: h.putheader('Accept', 'text/html')
  845.         """
  846.         if self.__state != _CS_REQ_STARTED:
  847.             raise CannotSendHeader()
  848.  
  849.         str = '%s: %s' % (header, value)
  850.         self._output(str)
  851.  
  852.     def endheaders(self):
  853.         """Indicate that the last header line has been sent to the server."""
  854.  
  855.         if self.__state == _CS_REQ_STARTED:
  856.             self.__state = _CS_REQ_SENT
  857.         else:
  858.             raise CannotSendHeader()
  859.  
  860.         self._send_output()
  861.  
  862.     def request(self, method, url, body=None, headers={}):
  863.         """Send a complete request to the server."""
  864.  
  865.         try:
  866.             self._send_request(method, url, body, headers)
  867.         except socket.error, v:
  868.             # trap 'Broken pipe' if we're allowed to automatically reconnect
  869.             if v[0] != 32 or not self.auto_open:
  870.                 raise
  871.             # try one more time
  872.             self._send_request(method, url, body, headers)
  873.  
  874.     def _send_request(self, method, url, body, headers):
  875.         # honour explicitly requested Host: and Accept-Encoding headers
  876.         header_names = dict.fromkeys([k.lower() for k in headers])
  877.         skips = {}
  878.         if 'host' in header_names:
  879.             skips['skip_host'] = 1
  880.         if 'accept-encoding' in header_names:
  881.             skips['skip_accept_encoding'] = 1
  882.  
  883.         self.putrequest(method, url, **skips)
  884.  
  885.         if body and ('content-length' not in header_names):
  886.             self.putheader('Content-Length', str(len(body)))
  887.         for hdr, value in headers.iteritems():
  888.             self.putheader(hdr, value)
  889.         self.endheaders()
  890.  
  891.         if body:
  892.             self.send(body)
  893.  
  894.     def getresponse(self):
  895.         "Get the response from the server."
  896.  
  897.         # if a prior response has been completed, then forget about it.
  898.         if self.__response and self.__response.isclosed():
  899.             self.__response = None
  900.  
  901.         #
  902.         # if a prior response exists, then it must be completed (otherwise, we
  903.         # cannot read this response's header to determine the connection-close
  904.         # behavior)
  905.         #
  906.         # note: if a prior response existed, but was connection-close, then the
  907.         # socket and response were made independent of this HTTPConnection
  908.         # object since a new request requires that we open a whole new
  909.         # connection
  910.         #
  911.         # this means the prior response had one of two states:
  912.         #   1) will_close: this connection was reset and the prior socket and
  913.         #                  response operate independently
  914.         #   2) persistent: the response was retained and we await its
  915.         #                  isclosed() status to become true.
  916.         #
  917.         if self.__state != _CS_REQ_SENT or self.__response:
  918.             raise ResponseNotReady()
  919.  
  920.         if self.debuglevel > 0:
  921.             response = self.response_class(self.sock, self.debuglevel,
  922.                                            strict=self.strict,
  923.                                            method=self._method)
  924.         else:
  925.             response = self.response_class(self.sock, strict=self.strict,
  926.                                            method=self._method)
  927.  
  928.         response.begin()
  929.         assert response.will_close != _UNKNOWN
  930.         self.__state = _CS_IDLE
  931.  
  932.         if response.will_close:
  933.             # this effectively passes the connection to the response
  934.             self.close()
  935.         else:
  936.             # remember this, so we can tell when it is complete
  937.             self.__response = response
  938.  
  939.         return response
  940.  
  941. # The next several classes are used to define FakeSocket, a socket-like
  942. # interface to an SSL connection.
  943.  
  944. # The primary complexity comes from faking a makefile() method.  The
  945. # standard socket makefile() implementation calls dup() on the socket
  946. # file descriptor.  As a consequence, clients can call close() on the
  947. # parent socket and its makefile children in any order.  The underlying
  948. # socket isn't closed until they are all closed.
  949.  
  950. # The implementation uses reference counting to keep the socket open
  951. # until the last client calls close().  SharedSocket keeps track of
  952. # the reference counting and SharedSocketClient provides an constructor
  953. # and close() method that call incref() and decref() correctly.
  954.  
  955. class SharedSocket:
  956.  
  957.     def __init__(self, sock):
  958.         self.sock = sock
  959.         self._refcnt = 0
  960.  
  961.     def incref(self):
  962.         self._refcnt += 1
  963.  
  964.     def decref(self):
  965.         self._refcnt -= 1
  966.         assert self._refcnt >= 0
  967.         if self._refcnt == 0:
  968.             self.sock.close()
  969.  
  970.     def __del__(self):
  971.         self.sock.close()
  972.  
  973. class SharedSocketClient:
  974.  
  975.     def __init__(self, shared):
  976.         self._closed = 0
  977.         self._shared = shared
  978.         self._shared.incref()
  979.         self._sock = shared.sock
  980.  
  981.     def close(self):
  982.         if not self._closed:
  983.             self._shared.decref()
  984.             self._closed = 1
  985.             self._shared = None
  986.  
  987. class SSLFile(SharedSocketClient):
  988.     """File-like object wrapping an SSL socket."""
  989.  
  990.     BUFSIZE = 8192
  991.  
  992.     def __init__(self, sock, ssl, bufsize=None):
  993.         SharedSocketClient.__init__(self, sock)
  994.         self._ssl = ssl
  995.         self._buf = ''
  996.         self._bufsize = bufsize or self.__class__.BUFSIZE
  997.  
  998.     def _read(self):
  999.         buf = ''
  1000.         # put in a loop so that we retry on transient errors
  1001.         while True:
  1002.             try:
  1003.                 buf = self._ssl.read(self._bufsize)
  1004.             except socket.sslerror, err:
  1005.                 if (err[0] == socket.SSL_ERROR_WANT_READ
  1006.                     or err[0] == socket.SSL_ERROR_WANT_WRITE):
  1007.                     continue
  1008.                 if (err[0] == socket.SSL_ERROR_ZERO_RETURN
  1009.                     or err[0] == socket.SSL_ERROR_EOF):
  1010.                     break
  1011.                 raise
  1012.             except socket.error, err:
  1013.                 if err[0] == errno.EINTR:
  1014.                     continue
  1015.                 if err[0] == errno.EBADF:
  1016.                     # XXX socket was closed?
  1017.                     break
  1018.                 raise
  1019.             else:
  1020.                 break
  1021.         return buf
  1022.  
  1023.     def read(self, size=None):
  1024.         L = [self._buf]
  1025.         avail = len(self._buf)
  1026.         while size is None or avail < size:
  1027.             s = self._read()
  1028.             if s == '':
  1029.                 break
  1030.             L.append(s)
  1031.             avail += len(s)
  1032.         all = "".join(L)
  1033.         if size is None:
  1034.             self._buf = ''
  1035.             return all
  1036.         else:
  1037.             self._buf = all[size:]
  1038.             return all[:size]
  1039.  
  1040.     def readline(self):
  1041.         L = [self._buf]
  1042.         self._buf = ''
  1043.         while 1:
  1044.             i = L[-1].find("\n")
  1045.             if i >= 0:
  1046.                 break
  1047.             s = self._read()
  1048.             if s == '':
  1049.                 break
  1050.             L.append(s)
  1051.         if i == -1:
  1052.             # loop exited because there is no more data
  1053.             return "".join(L)
  1054.         else:
  1055.             all = "".join(L)
  1056.             # XXX could do enough bookkeeping not to do a 2nd search
  1057.             i = all.find("\n") + 1
  1058.             line = all[:i]
  1059.             self._buf = all[i:]
  1060.             return line
  1061.  
  1062.     def readlines(self, sizehint=0):
  1063.         total = 0
  1064.         list = []
  1065.         while True:
  1066.             line = self.readline()
  1067.             if not line:
  1068.                 break
  1069.             list.append(line)
  1070.             total += len(line)
  1071.             if sizehint and total >= sizehint:
  1072.                 break
  1073.         return list
  1074.  
  1075.     def fileno(self):
  1076.         return self._sock.fileno()
  1077.  
  1078.     def __iter__(self):
  1079.         return self
  1080.  
  1081.     def next(self):
  1082.         line = self.readline()
  1083.         if not line:
  1084.             raise StopIteration
  1085.         return line
  1086.  
  1087. class FakeSocket(SharedSocketClient):
  1088.  
  1089.     class _closedsocket:
  1090.         def __getattr__(self, name):
  1091.             raise error(9, 'Bad file descriptor')
  1092.  
  1093.     def __init__(self, sock, ssl):
  1094.         sock = SharedSocket(sock)
  1095.         SharedSocketClient.__init__(self, sock)
  1096.         self._ssl = ssl
  1097.  
  1098.     def close(self):
  1099.         SharedSocketClient.close(self)
  1100.         self._sock = self.__class__._closedsocket()
  1101.  
  1102.     def makefile(self, mode, bufsize=None):
  1103.         if mode != 'r' and mode != 'rb':
  1104.             raise UnimplementedFileMode()
  1105.         return SSLFile(self._shared, self._ssl, bufsize)
  1106.  
  1107.     def send(self, stuff, flags = 0):
  1108.         return self._ssl.write(stuff)
  1109.  
  1110.     sendall = send
  1111.  
  1112.     def recv(self, len = 1024, flags = 0):
  1113.         return self._ssl.read(len)
  1114.  
  1115.     def __getattr__(self, attr):
  1116.         return getattr(self._sock, attr)
  1117.  
  1118.  
  1119. class HTTPSConnection(HTTPConnection):
  1120.     "This class allows communication via SSL."
  1121.  
  1122.     default_port = HTTPS_PORT
  1123.  
  1124.     def __init__(self, host, port=None, key_file=None, cert_file=None,
  1125.                  strict=None):
  1126.         HTTPConnection.__init__(self, host, port, strict)
  1127.         self.key_file = key_file
  1128.         self.cert_file = cert_file
  1129.  
  1130.     def connect(self):
  1131.         "Connect to a host on a given (SSL) port."
  1132.  
  1133.         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  1134.         sock.connect((self.host, self.port))
  1135.         ssl = socket.ssl(sock, self.key_file, self.cert_file)
  1136.         self.sock = FakeSocket(sock, ssl)
  1137.  
  1138.  
  1139. class HTTP:
  1140.     "Compatibility class with httplib.py from 1.5."
  1141.  
  1142.     _http_vsn = 10
  1143.     _http_vsn_str = 'HTTP/1.0'
  1144.  
  1145.     debuglevel = 0
  1146.  
  1147.     _connection_class = HTTPConnection
  1148.  
  1149.     def __init__(self, host='', port=None, strict=None):
  1150.         "Provide a default host, since the superclass requires one."
  1151.  
  1152.         # some joker passed 0 explicitly, meaning default port
  1153.         if port == 0:
  1154.             port = None
  1155.  
  1156.         # Note that we may pass an empty string as the host; this will throw
  1157.         # an error when we attempt to connect. Presumably, the client code
  1158.         # will call connect before then, with a proper host.
  1159.         self._setup(self._connection_class(host, port, strict))
  1160.  
  1161.     def _setup(self, conn):
  1162.         self._conn = conn
  1163.  
  1164.         # set up delegation to flesh out interface
  1165.         self.send = conn.send
  1166.         self.putrequest = conn.putrequest
  1167.         self.endheaders = conn.endheaders
  1168.         self.set_debuglevel = conn.set_debuglevel
  1169.  
  1170.         conn._http_vsn = self._http_vsn
  1171.         conn._http_vsn_str = self._http_vsn_str
  1172.  
  1173.         self.file = None
  1174.  
  1175.     def connect(self, host=None, port=None):
  1176.         "Accept arguments to set the host/port, since the superclass doesn't."
  1177.  
  1178.         if host is not None:
  1179.             self._conn._set_hostport(host, port)
  1180.         self._conn.connect()
  1181.  
  1182.     def getfile(self):
  1183.         "Provide a getfile, since the superclass' does not use this concept."
  1184.         return self.file
  1185.  
  1186.     def putheader(self, header, *values):
  1187.         "The superclass allows only one value argument."
  1188.         self._conn.putheader(header, '\r\n\t'.join(values))
  1189.  
  1190.     def getreply(self):
  1191.         """Compat definition since superclass does not define it.
  1192.  
  1193.         Returns a tuple consisting of:
  1194.         - server status code (e.g. '200' if all goes well)
  1195.         - server "reason" corresponding to status code
  1196.         - any RFC822 headers in the response from the server
  1197.         """
  1198.         try:
  1199.             response = self._conn.getresponse()
  1200.         except BadStatusLine, e:
  1201.             ### hmm. if getresponse() ever closes the socket on a bad request,
  1202.             ### then we are going to have problems with self.sock
  1203.  
  1204.             ### should we keep this behavior? do people use it?
  1205.             # keep the socket open (as a file), and return it
  1206.             self.file = self._conn.sock.makefile('rb', 0)
  1207.  
  1208.             # close our socket -- we want to restart after any protocol error
  1209.             self.close()
  1210.  
  1211.             self.headers = None
  1212.             return -1, e.line, None
  1213.  
  1214.         self.headers = response.msg
  1215.         self.file = response.fp
  1216.         return response.status, response.reason, response.msg
  1217.  
  1218.     def close(self):
  1219.         self._conn.close()
  1220.  
  1221.         # note that self.file == response.fp, which gets closed by the
  1222.         # superclass. just clear the object ref here.
  1223.         ### hmm. messy. if status==-1, then self.file is owned by us.
  1224.         ### well... we aren't explicitly closing, but losing this ref will
  1225.         ### do it
  1226.         self.file = None
  1227.  
  1228. if hasattr(socket, 'ssl'):
  1229.     class HTTPS(HTTP):
  1230.         """Compatibility with 1.5 httplib interface
  1231.  
  1232.         Python 1.5.2 did not have an HTTPS class, but it defined an
  1233.         interface for sending http requests that is also useful for
  1234.         https.
  1235.         """
  1236.  
  1237.         _connection_class = HTTPSConnection
  1238.  
  1239.         def __init__(self, host='', port=None, key_file=None, cert_file=None,
  1240.                      strict=None):
  1241.             # provide a default host, pass the X509 cert info
  1242.  
  1243.             # urf. compensate for bad input.
  1244.             if port == 0:
  1245.                 port = None
  1246.             self._setup(self._connection_class(host, port, key_file,
  1247.                                                cert_file, strict))
  1248.  
  1249.             # we never actually use these for anything, but we keep them
  1250.             # here for compatibility with post-1.5.2 CVS.
  1251.             self.key_file = key_file
  1252.             self.cert_file = cert_file
  1253.  
  1254.  
  1255. class HTTPException(Exception):
  1256.     # Subclasses that define an __init__ must call Exception.__init__
  1257.     # or define self.args.  Otherwise, str() will fail.
  1258.     pass
  1259.  
  1260. class NotConnected(HTTPException):
  1261.     pass
  1262.  
  1263. class InvalidURL(HTTPException):
  1264.     pass
  1265.  
  1266. class UnknownProtocol(HTTPException):
  1267.     def __init__(self, version):
  1268.         self.args = version,
  1269.         self.version = version
  1270.  
  1271. class UnknownTransferEncoding(HTTPException):
  1272.     pass
  1273.  
  1274. class UnimplementedFileMode(HTTPException):
  1275.     pass
  1276.  
  1277. class IncompleteRead(HTTPException):
  1278.     def __init__(self, partial):
  1279.         self.args = partial,
  1280.         self.partial = partial
  1281.  
  1282. class ImproperConnectionState(HTTPException):
  1283.     pass
  1284.  
  1285. class CannotSendRequest(ImproperConnectionState):
  1286.     pass
  1287.  
  1288. class CannotSendHeader(ImproperConnectionState):
  1289.     pass
  1290.  
  1291. class ResponseNotReady(ImproperConnectionState):
  1292.     pass
  1293.  
  1294. class BadStatusLine(HTTPException):
  1295.     def __init__(self, line):
  1296.         self.args = line,
  1297.         self.line = line
  1298.  
  1299. # for backwards compatibility
  1300. error = HTTPException
  1301.  
  1302. class LineAndFileWrapper:
  1303.     """A limited file-like object for HTTP/0.9 responses."""
  1304.  
  1305.     # The status-line parsing code calls readline(), which normally
  1306.     # get the HTTP status line.  For a 0.9 response, however, this is
  1307.     # actually the first line of the body!  Clients need to get a
  1308.     # readable file object that contains that line.
  1309.  
  1310.     def __init__(self, line, file):
  1311.         self._line = line
  1312.         self._file = file
  1313.         self._line_consumed = 0
  1314.         self._line_offset = 0
  1315.         self._line_left = len(line)
  1316.  
  1317.     def __getattr__(self, attr):
  1318.         return getattr(self._file, attr)
  1319.  
  1320.     def _done(self):
  1321.         # called when the last byte is read from the line.  After the
  1322.         # call, all read methods are delegated to the underlying file
  1323.         # object.
  1324.         self._line_consumed = 1
  1325.         self.read = self._file.read
  1326.         self.readline = self._file.readline
  1327.         self.readlines = self._file.readlines
  1328.  
  1329.     def read(self, amt=None):
  1330.         if self._line_consumed:
  1331.             return self._file.read(amt)
  1332.         assert self._line_left
  1333.         if amt is None or amt > self._line_left:
  1334.             s = self._line[self._line_offset:]
  1335.             self._done()
  1336.             if amt is None:
  1337.                 return s + self._file.read()
  1338.             else:
  1339.                 return s + self._file.read(amt - len(s))
  1340.         else:
  1341.             assert amt <= self._line_left
  1342.             i = self._line_offset
  1343.             j = i + amt
  1344.             s = self._line[i:j]
  1345.             self._line_offset = j
  1346.             self._line_left -= amt
  1347.             if self._line_left == 0:
  1348.                 self._done()
  1349.             return s
  1350.  
  1351.     def readline(self):
  1352.         if self._line_consumed:
  1353.             return self._file.readline()
  1354.         assert self._line_left
  1355.         s = self._line[self._line_offset:]
  1356.         self._done()
  1357.         return s
  1358.  
  1359.     def readlines(self, size=None):
  1360.         if self._line_consumed:
  1361.             return self._file.readlines(size)
  1362.         assert self._line_left
  1363.         L = [self._line[self._line_offset:]]
  1364.         self._done()
  1365.         if size is None:
  1366.             return L + self._file.readlines()
  1367.         else:
  1368.             return L + self._file.readlines(size)
  1369.  
  1370. def test():
  1371.     """Test this module.
  1372.  
  1373.     A hodge podge of tests collected here, because they have too many
  1374.     external dependencies for the regular test suite.
  1375.     """
  1376.  
  1377.     import sys
  1378.     import getopt
  1379.     opts, args = getopt.getopt(sys.argv[1:], 'd')
  1380.     dl = 0
  1381.     for o, a in opts:
  1382.         if o == '-d': dl = dl + 1
  1383.     host = 'www.python.org'
  1384.     selector = '/'
  1385.     if args[0:]: host = args[0]
  1386.     if args[1:]: selector = args[1]
  1387.     h = HTTP()
  1388.     h.set_debuglevel(dl)
  1389.     h.connect(host)
  1390.     h.putrequest('GET', selector)
  1391.     h.endheaders()
  1392.     status, reason, headers = h.getreply()
  1393.     print 'status =', status
  1394.     print 'reason =', reason
  1395.     print "read", len(h.getfile().read())
  1396.     print
  1397.     if headers:
  1398.         for header in headers.headers: print header.strip()
  1399.     print
  1400.  
  1401.     # minimal test that code to extract host from url works
  1402.     class HTTP11(HTTP):
  1403.         _http_vsn = 11
  1404.         _http_vsn_str = 'HTTP/1.1'
  1405.  
  1406.     h = HTTP11('www.python.org')
  1407.     h.putrequest('GET', 'http://www.python.org/~jeremy/')
  1408.     h.endheaders()
  1409.     h.getreply()
  1410.     h.close()
  1411.  
  1412.     if hasattr(socket, 'ssl'):
  1413.  
  1414.         for host, selector in (('sourceforge.net', '/projects/python'),
  1415.                                ):
  1416.             print "https://%s%s" % (host, selector)
  1417.             hs = HTTPS()
  1418.             hs.set_debuglevel(dl)
  1419.             hs.connect(host)
  1420.             hs.putrequest('GET', selector)
  1421.             hs.endheaders()
  1422.             status, reason, headers = hs.getreply()
  1423.             print 'status =', status
  1424.             print 'reason =', reason
  1425.             print "read", len(hs.getfile().read())
  1426.             print
  1427.             if headers:
  1428.                 for header in headers.headers: print header.strip()
  1429.             print
  1430.  
  1431. if __name__ == '__main__':
  1432.     test()
  1433.